package com.estate.system.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.estate.common.core.domain.entity.SysUser;
import com.estate.common.utils.PageUtils;
import com.estate.system.domain.Enquiry;
import com.estate.system.domain.report.boss.agentperformance.AgentClientCount;
import com.estate.system.domain.report.boss.area.SuburbDistribution;
import com.estate.system.domain.report.boss.clientservice.ConnectionRecommendationRelation;
import com.estate.system.domain.report.boss.clientservice.RecommendationStatus;
import com.estate.system.domain.report.boss.clientservice.ServiceTypeDistribution;
import com.estate.system.domain.report.boss.timeTrends.DayOfWeekRequest;
import com.estate.system.domain.report.boss.timeTrends.HourlyRequest;
import com.estate.system.domain.report.boss.timeTrends.MonthlyTrendPoint;
import com.estate.system.domain.vo.ClientResult;
import com.estate.system.mapper.DataEnquiryMapper;
import com.estate.system.mapper.DataListingsMapper;
import com.estate.system.mapper.SysUserMapper;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class DataEnquiriesServiceImpl extends ServiceImpl<DataEnquiryMapper, Enquiry> {

    private static final Logger log = LoggerFactory.getLogger(DataListingsServiceImpl.class);

    @Resource
    private DataEnquiryMapper dataEnquiriesMapper;
    @Resource
    private DataListingsMapper dataListingsMapper;
    @Autowired
    private SysUserMapper userMapper;

    public Map<String, Object> getSevenDayNewEnquire(Map<String, Object> param) {
        log.info("获取近七天新增客户咨询数量请求参数={}", param);
        Map<String, Object> result = new HashMap<>();
        try {
           // 获取悉尼（澳大利亚东部）的当前时间
            ZoneId australiaSydney = ZoneId.of("Australia/Sydney");
            ZonedDateTime now = ZonedDateTime.now(australiaSydney);
            // 计算7天前的时间
            int sevenDays = param.get("XDays") == null ? 7 : Integer.parseInt(param.get("XDays").toString());
            ZonedDateTime sevenDaysAgo = now.minusDays(sevenDays);

            // 计算14天前的时间
            ZonedDateTime fourteenDaysAgo = now.minusDays(sevenDays * 2L);

            SysUser sysUser = new SysUser();
            List<String> emailList = userMapper.selectUserList(sysUser).stream().map(SysUser::getEmail).collect(Collectors.toList());

            // 设置日期时间格式化器
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            Long sevenDaysAgoCount = dataEnquiriesMapper.getSevenDayNewEnquire(sevenDaysAgo.format(formatter), now.format(formatter),emailList);
            Long fourteenDaysAgoCount = dataEnquiriesMapper.getSevenDayNewEnquire(fourteenDaysAgo.format(formatter), sevenDaysAgo.format(formatter),emailList);
            if(null == sevenDaysAgoCount) {
                sevenDaysAgoCount = 0L;
            }
            if(null == fourteenDaysAgoCount) {
                fourteenDaysAgoCount = 0L;
            }
            result.put("sevenDaysAgoCount", sevenDaysAgoCount);
            result.put("fourteenDaysAgoCount", fourteenDaysAgoCount);

            if (null == sevenDaysAgoCount || sevenDaysAgoCount == 0) {
                result.put("addPercentage", 0);
            }
            if (null == fourteenDaysAgoCount || fourteenDaysAgoCount == 0) {
                result.put("addPercentage", 100);
            }
            //获取环比
            if (null != fourteenDaysAgoCount && null != sevenDaysAgoCount) {
                double addPercentage = (double) (sevenDaysAgoCount - fourteenDaysAgoCount) / fourteenDaysAgoCount;
                result.put("addPercentage", addPercentage);
            }
        } catch (Exception e) {
            log.error("获取近七天新增客户咨询数量异常......", e);
        }
        return result;
    }

    public Map<String, Object> getSevenDayNewListing(Map<String, Object> param) {
        log.info("获取7天新增房产数量请求参数={}", param);

        Map<String, Object> result = new HashMap<>();
        try {
            // 获取悉尼（澳大利亚东部）的当前时间
            ZoneId australiaSydney = ZoneId.of("Australia/Sydney");
            ZonedDateTime now = ZonedDateTime.now(australiaSydney);
            // 计算7天前的时间
            int sevenDays = param.get("XDays") == null ? 7 : Integer.parseInt(param.get("XDays").toString());
            ZonedDateTime sevenDaysAgo = now.minusDays(sevenDays);

            // 计算14天前的时间
            ZonedDateTime fourteenDaysAgo = now.minusDays(sevenDays * 2L);
            SysUser sysUser = new SysUser();
            List<String> emailList = userMapper.selectUserList(sysUser).stream().map(SysUser::getEmail).collect(Collectors.toList());

            // 设置日期时间格式化器
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            Long sevenDaysAgoCount = dataListingsMapper.querySevenDaysNewListing(sevenDaysAgo.format(formatter), now.format(formatter),emailList);
            Long fourteenDaysAgoCount = dataListingsMapper.querySevenDaysNewListing(fourteenDaysAgo.format(formatter), sevenDaysAgo.format(formatter),emailList);

            result.put("sevenDaysAgoCount", sevenDaysAgoCount);
            result.put("fourteenDaysAgoCount", fourteenDaysAgoCount);
            if (null == sevenDaysAgoCount || sevenDaysAgoCount == 0) {
                result.put("addPercentage", 0d);
            }
            if (null == fourteenDaysAgoCount || fourteenDaysAgoCount == 0) {
                result.put("addPercentage", 100d);
            }
            //获取环比
            if (null != fourteenDaysAgoCount && null != sevenDaysAgoCount) {
                double addPercentage = (double) (sevenDaysAgoCount - fourteenDaysAgoCount) / fourteenDaysAgoCount;
                result.put("addPercentage", addPercentage);
            }
        } catch (Exception e) {
            log.error("获取近七天新增房产数量异常......", e);
        }
        return result;
    }

    public List<Map<String, Object>> getEnquireByEnquireType(Map<String, Object> param) {
        log.info("获取近七天新增客户咨询数量请求参数={}", param);
        List<Map<String, Object>> listingCountByArea = new ArrayList<>();
        try {
            // 获取悉尼（澳大利亚东部）的当前时间
            ZoneId australiaSydney = ZoneId.of("Australia/Sydney");
            ZonedDateTime now = ZonedDateTime.now(australiaSydney);
            // 计算7天前的时间
            int sevenDays = param.get("XDays") == null ? 7 : Integer.parseInt(param.get("XDays").toString());
            ZonedDateTime sevenDaysAgo = now.minusDays(sevenDays);
            // 设置日期时间格式化器
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            SysUser sysUser = new SysUser();
            List<String> emailList = userMapper.selectUserList(sysUser).stream().map(SysUser::getEmail).collect(Collectors.toList());

            listingCountByArea = dataEnquiriesMapper.getEnquireByEnquireType(sevenDaysAgo.format(formatter), now.format(formatter),emailList);
        } catch (Exception e) {
            log.error("获取近七天新增客户咨询数量异常......", e);
        }
        return listingCountByArea;
    }

    public Map<String, Object> getUpcomingTasks(Map<String, Object> param) {
        Map<String, Object> result = new HashMap<>();
        // 获取悉尼（澳大利亚东部）的当前时间
        ZoneId australiaSydney = ZoneId.of("Australia/Sydney");
        ZonedDateTime now = ZonedDateTime.now(australiaSydney);
        // 计算7天前的时间
        int sevenDays = param.get("XDays") == null ? 7 : Integer.parseInt(param.get("XDays").toString());
        ZonedDateTime sevenDaysAgo = now.minusDays(sevenDays);
        // 计算14天前的时间
        ZonedDateTime fourteenDaysAgo = now.minusDays(sevenDays * 2L);
        // 设置日期时间格式化器
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 获取统计最近7天数据
        int lightServiceCount = dataEnquiriesMapper.selectLightServiceCount(sevenDaysAgo.format(formatter), now.format(formatter));
        int deepServiceCount = dataEnquiriesMapper.selectDeepServiceCount(sevenDaysAgo.format(formatter), now.format(formatter));
        int totalTaskCount = lightServiceCount + deepServiceCount;
        //统计上一个7天的数据
        int lightServiceCountLastWeek = dataEnquiriesMapper.selectLightServiceCount(fourteenDaysAgo.format(formatter), sevenDaysAgo.format(formatter));
        int deepServiceCountLastWeek = dataEnquiriesMapper.selectDeepServiceCount(fourteenDaysAgo.format(formatter), sevenDaysAgo.format(formatter));
        int totalTaskCountLastWeek = lightServiceCountLastWeek + deepServiceCountLastWeek;
        //本周任务数量
        result.put("upcomingTasks", totalTaskCount);
        //较上一周增长率
        long upOrDown = 0;
        if(totalTaskCountLastWeek != 0){
            upOrDown =  (totalTaskCount - totalTaskCountLastWeek) /totalTaskCountLastWeek;
        }else{
            if(totalTaskCount != 0){
                upOrDown = 100;
            }
        }
        result.put("upOrDown", upOrDown +"%");
        return result;
    }
    public List<String> getDetailTask(Map<String, Object> param) {
        List<String> tasks = new ArrayList<>();
        // 获取悉尼（澳大利亚东部）的当前时间
        ZoneId australiaSydney = ZoneId.of("Australia/Sydney");
        ZonedDateTime now = ZonedDateTime.now(australiaSydney);
        // 设置日期时间格式化器
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        // 获取统计最近7天数据
        String lightServiceEmail = dataEnquiriesMapper.selectLightServiceEmail(now.format(formatter), now.format(formatter));
        if(StringUtils.isNotBlank(lightServiceEmail)){
            String task1 = "Send recommendation message to "+lightServiceEmail+" clients.";
            tasks.add(task1);
        }
        List<Map<String,Object>> deepServiceCount = dataEnquiriesMapper.selectDeepServiceDetail(now.format(formatter), now.format(formatter));
        if(!CollectionUtils.isEmpty(tasks)){
            deepServiceCount = deepServiceCount.stream().limit(4).collect(Collectors.toList());
        }
        deepServiceCount.forEach(deepService -> {
                String name = deepService.get("name").toString();
                String method = deepService.get("method").toString();
                String task = "Provide services to "+name+" of a " + method;
                tasks.add(task);
        });
        return tasks;
    }

    public List<Map<String, Object>> getTrendsInRentalAmounts(Map<String, Object> paramData) {
        SysUser sysUser = new SysUser();
        List<String> emailList = userMapper.selectUserList(sysUser).stream().map(SysUser::getEmail).collect(Collectors.toList());
        return dataEnquiriesMapper.getTrendsInRentalAmounts(paramData,emailList);

    }

    public List<Map<String, Object>> getTrendOfTransactions(Map<String, Object> paramData) {
        SysUser sysUser = new SysUser();
        List<String> emailList = userMapper.selectUserList(sysUser).stream().map(SysUser::getEmail).collect(Collectors.toList());

        return dataEnquiriesMapper.getTrendOfTransactions(paramData,emailList);
    }

    public List<Map<String, Object>> getRankingOfTransactionsNumber(Map<String, Object> paramData) {
        SysUser sysUser = new SysUser();
        List<String> emailList = userMapper.selectUserList(sysUser).stream().map(SysUser::getEmail).collect(Collectors.toList());

        return dataEnquiriesMapper.getRankingOfTransactionsNumber(paramData,emailList);

    }

    public List<Map<String, Object>> getTrendsInTransactionAmounts(Map<String, Object> paramData, List<String> emailList) {

        return dataEnquiriesMapper.getTrendsInTransactionAmounts(paramData,emailList);

    }

    public Map<String, Object> getDauDetail(Map<String, Object> paramData) {
        return dataEnquiriesMapper.getDauDetail(paramData);
    }

    public List<Map<String, Object>> getUserActivityTrend(Map<String, Object> paramData) {
        return dataEnquiriesMapper.getUserActivityTrend(paramData);


    }

    public List<SuburbDistribution> generateSuburbDistributionData(Map<String, Object> paramData) {
        List<SuburbDistribution> systemLogVoList = new ArrayList<>();
        SysUser sysUser = new SysUser();
        List<String> emailList = userMapper.selectUserList(sysUser).stream().map(SysUser::getEmail).collect(Collectors.toList());

        List<Map<String, Object>> userActivityTrendList = dataEnquiriesMapper.generateSuburbDistributionData(paramData,emailList);
        userActivityTrendList.forEach(activity -> {
            systemLogVoList.add(new SuburbDistribution(activity.get("region").toString(), Integer.parseInt(activity.get("enquiry_count").toString())));
        });
        return systemLogVoList;
    }

    public List<ServiceTypeDistribution> generateServiceTypeData(Map<String, Object> paramData) {
        List<ServiceTypeDistribution> serviceTypeDistributionList = new ArrayList<>();
        List<Map<String,Object>> queryResult = dataEnquiriesMapper.generateServiceTypeData();
        queryResult.forEach(serviceType -> {
            serviceTypeDistributionList.add(new ServiceTypeDistribution(serviceType.get("servicetype").toString(),Double.parseDouble(serviceType.get("percentage").toString()),""));
        });
        return serviceTypeDistributionList;
    }

    public List<RecommendationStatus> generateRecommendationStatusData(Map<String, Object> paramData) {
        List<RecommendationStatus> recommendationData = new ArrayList<>();
        List<Map<String,Object>> queryResult = dataEnquiriesMapper.generateRecommendationStatusData(paramData);
        queryResult.forEach(serviceType -> {
            recommendationData.add(new RecommendationStatus(serviceType.get("scorelevel").toString(),Double.parseDouble(serviceType.get("percentage").toString()),Integer.parseInt(serviceType.get("levelcount").toString())));
        });
        return recommendationData;
    }

    public List<ConnectionRecommendationRelation> generateConnectionRecommendationData(Map<String, Object> paramData) {
        List<ConnectionRecommendationRelation> connectionRecommendationRelationList = new ArrayList<>();
        List<Map<String,Object>> queryResult = dataEnquiriesMapper.generateConnectionRecommendationData(paramData);
        queryResult.forEach(serviceType -> {
            connectionRecommendationRelationList.add(new ConnectionRecommendationRelation(serviceType.get("servicetype").toString(),Double.parseDouble(serviceType.get("gtpercent").toString()),Double.parseDouble(serviceType.get("ltpercent").toString())));
        });
        return connectionRecommendationRelationList;
    }

    public List<AgentClientCount> createTopAgentsByClientCount(Map<String, Object> paramData) {
        List<AgentClientCount> agentClientCountList = new ArrayList<>();
        SysUser sysUser = new SysUser();
        List<String> emailList = userMapper.selectUserList(sysUser).stream().map(SysUser::getEmail).collect(Collectors.toList());

        List<Map<String, Object>> topAgentsByClientList = dataEnquiriesMapper.createTopAgentsByClientCount(paramData,emailList);
        for (Map<String, Object> stringObjectMap : topAgentsByClientList) {
            agentClientCountList.add(new AgentClientCount(stringObjectMap.get("agentname").toString(),Integer.parseInt(stringObjectMap.get("clientcount").toString())));
        }

        return agentClientCountList;
    }

    public List<MonthlyTrendPoint> createMonthlyTrendPointData(Map<String, Object> paramData) {
        List<MonthlyTrendPoint> monthlyTrendPointList = new ArrayList<>();
        SysUser sysUser = new SysUser();
        List<String> emailList = userMapper.selectUserList(sysUser).stream().map(SysUser::getEmail).collect(Collectors.toList());
        List<Map<String, Object>> monthlyTrendPointDataList = dataEnquiriesMapper.createMonthlyTrendPointData(paramData,emailList);
        for (Map<String, Object> stringObjectMap : monthlyTrendPointDataList) {
            monthlyTrendPointList.add(new MonthlyTrendPoint(stringObjectMap.get("consultdate").toString(),Integer.parseInt(stringObjectMap.get("dailycount").toString())));
        }
        return monthlyTrendPointList;
    }

    public List<DayOfWeekRequest> createDayOfWeekRequestData(Map<String, Object> paramData) {
        List<DayOfWeekRequest> dayOfWeekRequestList = new ArrayList<>();
        SysUser sysUser = new SysUser();
        List<String> emailList = userMapper.selectUserList(sysUser).stream().map(SysUser::getEmail).collect(Collectors.toList());
        List<Map<String, Object>> monthlyTrendPointDataList = dataEnquiriesMapper.createDayOfWeekRequestData(paramData,emailList);
        for (Map<String, Object> stringObjectMap : monthlyTrendPointDataList) {
            dayOfWeekRequestList.add(new DayOfWeekRequest(stringObjectMap.get("weeknumber").toString(), Integer.parseInt(stringObjectMap.get("weeklycount").toString())));
        }
        return dayOfWeekRequestList;
    }

    public List<HourlyRequest> createHourlyRequestData(Map<String, Object> paramData) {
        List<HourlyRequest> hourlyRequestList = new ArrayList<>();
        SysUser sysUser = new SysUser();
        List<String> emailList = userMapper.selectUserList(sysUser).stream().map(SysUser::getEmail).collect(Collectors.toList());
        List<Map<String, Object>> monthlyTrendPointDataList = dataEnquiriesMapper.createHourlyRequestData(paramData,emailList);
        for (Map<String, Object> stringObjectMap : monthlyTrendPointDataList) {
            hourlyRequestList.add(new HourlyRequest(Integer.parseInt(stringObjectMap.get("hourofday").toString()), Integer.parseInt(stringObjectMap.get("hourlycount").toString())));
        }
        return hourlyRequestList;
    }
    public Page<ClientResult> getMessageSent(ClientResult bo) {
        return dataEnquiriesMapper.getMessageSent(PageUtils.getPage(bo), bo);


    }
}